/*
 * Copyright (c) 2010.
 */

package com.mobile.framework.tag;

import com.mobile.framework.util.Constants;
import com.mobile.framework.util.PageList;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * Standard page navigator. usage: <app:page name="users"
 * searchForm="searchUserForm" showJumpBox="false" showRowSelect="true"
 * rowNumber="5,10,30">
 * name设置数据集(必须是PageList)的名称,searchForm设置相关查询表单的名称,如果设置该属性将自动生成相关javascript代码
 * showJumpBox 决定是否显示页面跳转框,showRowSelect决定是否显示每页记录数选择框,rowNumber决定可选的每页记录数
 * 除name属性,其他都是可选属性,缺省控制由config.property文件中page.jump.disable,page.rows配置决定
 */
public class PagerTag extends SimpleTagSupport {

    private String name;
    private String searchForm;
    private String styleType;
    private String scope;
    private String showJumpBox;// 是否显示跳转框
    private String showRowSelect;// 是否显示每页数选择框
    private String rowNumber;// 可选的每页记录数

    private PageList pageList;  //PageList

    public static final String TEMPLATE_PAGE = "/PageTag.html";    //script for page template
    public static final String ROWS_PER_PAGE_S = "10,15,20,30,60,100";  //每页显示记录数的下拉框选择
    public static final StringBuffer templatePageS; //StringBuffer for 分页模板脚本；


    public void doTag() throws JspException, IOException {

        StringBuffer results = new StringBuffer(templatePageS);//attention：new StringBuffer(templatePageS) is must;
        retrievePageList();     //retrieve the pageList
        showPageInfo(results);      //page info
        showRowSelect(results);     //select control for rowsPerPage
        showJavaScript(results);    //load javascript

        /*渲染分页页面*/
        renderPagerInfo(results.toString());
    }

    /**
     * retrieve the pageList
     */
    public void retrievePageList() {
        if (null == pageList) {
            if (null != name) {
                if (null == scope || "request".equals(scope)) {
                    pageList = (PageList) getJspContext().getAttribute(name, PageContext.REQUEST_SCOPE);
                } else if ("page".equals(scope)) {
                    pageList = (PageList) getJspContext().getAttribute(name, PageContext.PAGE_SCOPE);
                } else if ("session".equals(scope)) {
                    pageList = (PageList) getJspContext().getAttribute(name, PageContext.SESSION_SCOPE);
                } else if ("application".equals(scope)) {
                    pageList = (PageList) getJspContext().getAttribute(name, PageContext.APPLICATION_SCOPE);
                } else {
                    pageList = new PageList();
                }
            } else {
                pageList = new PageList();
            }
        }
    }

    // 显示分页信息和链接
    private void showPageInfo(StringBuffer results)
            throws JspException {

        int currentPage = pageList.getCurrentPage();
        int pageCount = pageList.getPageCount();
        int totalRowCount = pageList.getTotalRowCount();

        // 合计页数
        parseTags(results, "###currentPage###", null, String.valueOf(currentPage));
        parseTags(results, "###pageCount###", null, String.valueOf(pageCount));
        parseTags(results, "###totalRowCount###", null, String.valueOf(totalRowCount));

        // 第一页
        if (currentPage > 1 && pageCount > 1) {
            parseTags(results, "<!--startFirstPageHref-->", null, "");
            parseTags(results, "<!--endFirstPageHref-->", null, "");
            parseTags(results, "<!--startFirstPageSpan-->", "<!--endFirstPageSpan-->", "");
        } else {
            parseTags(results, "<!--startFirstPageHref-->", "<!--endFirstPageHref-->", "");
            parseTags(results, "<!--startFirstPageSpan-->", null, "");
            parseTags(results, "<!--endFirstPageSpan-->", null, "");

        }

        // 上一页
        if (currentPage > 1) {
            parseTags(results, "<!--startPreviousPageHref-->", null, "");
            parseTags(results, "<!--endPreviousPageHref-->", null, "");
            parseTags(results, "<!--startPreviousPageSpan-->", "<!--endPreviousPageSpan-->", "");
            parseTags(results, "###previousPage###", null, String.valueOf(currentPage - 1));
        } else {
            parseTags(results, "<!--startPreviousPageHref-->", "<!--endPreviousPageHref-->", "");
            parseTags(results, "<!--startPreviousPageSpan-->", null, "");
            parseTags(results, "<!--endPreviousPageSpan-->", null, "");
        }

        // 下一页
        if (currentPage < pageCount) {
            parseTags(results, "<!--startNextPageHref-->", null, "");
            parseTags(results, "<!--endNextPageHref-->", null, "");
            parseTags(results, "<!--startNextPageSpan-->", "<!--endNextPageSpan-->", "");
            parseTags(results, "###nextPage###", null, String.valueOf(currentPage + 1));
        } else {
            parseTags(results, "<!--startNextPageHref-->", "<!--endNextPageHref-->", "");
            parseTags(results, "<!--startNextPageSpan-->", null, "");
            parseTags(results, "<!--endNextPageSpan-->", null, "");
        }

        // 最后一页
        if (currentPage >= pageCount) {
            parseTags(results, "<!--startLastPageHref-->", "<!--endLastPageHref-->", "");
            parseTags(results, "<!--startLastPageSpan-->", null, "");
            parseTags(results, "<!--endLastPageSpan-->", null, "");
        } else {
            parseTags(results, "<!--startLastPageHref-->", null, "");
            parseTags(results, "<!--endLastPageHref-->", null, "");
            parseTags(results, "<!--startLastPageSpan-->", "<!--endLastPageSpan-->", "");
            parseTags(results, "###lastPage###", null, String.valueOf(pageCount));

        }

        //跳转页码框
        if (null != showJumpBox && "true".equals(showJumpBox)) {
            parseTags(results, "<!--startJumpPage-->", null, "");
            parseTags(results, "<!--endJumpPage-->", null, "");
        } else {
            parseTags(results, "<!--startJumpPage-->", "<!--endJumpPage-->", "");
        }
    }


    // 每页记录数选择框
    private void showRowSelect(StringBuffer results) throws JspException {
        // 每页记录数选择框
        if (null != showRowSelect && "true".equals(showRowSelect)) {
            //过滤 results
            parseTags(results, "<!--startRowsPerPage-->", null, "");
            parseTags(results, "<!--endRowsPerPage-->", null, "");

            String curRows = ((PageContext)getJspContext()).getRequest().getParameter("rowsPerPage");
            if (null == curRows || "".equals(curRows)) {
                curRows = Constants.ROWS_PER_PAGE;
            }
            // 可选每页记录数的值
            String rowsValueList = this.rowNumber;
            if (null == rowsValueList || "".equals(rowsValueList)) {
                // 从配置文件取可选记录数
                rowsValueList = ROWS_PER_PAGE_S;
            }
            StringTokenizer st = new StringTokenizer(rowsValueList, ",");
            StringBuffer options = new StringBuffer("");
            // 生成下拉框
            while (st.hasMoreTokens()) {
                String row = st.nextToken();
                options.append("<option value=\"" + row + "\"");
                if (row.equals(curRows)) {
                    options.append(" selected ");
                }
                options.append(">" + row + "</option>");
            }
            parseTags(results, "###rowNumber###", null, options.toString());
        } else {
            parseTags(results, "<!--startRowsPerPage-->", "<!--endRowsPerPage-->", "");
        }
    }

    // javascript
    private void showJavaScript(StringBuffer results) throws JspException {

        if (null != searchForm && !"".equals(searchForm)) {
            parseTags(results, "###searchForm###", null, searchForm);
            parseTags(results, "###maxRows###", null, String.valueOf(pageList.getPageCount()));

        } else {
            parseTags(results, "<!--startJavascript-->", "<!--endJavascript-->", "");
        }
    }

    private void parseTags(StringBuffer sb, String from, String to, String replace) {
        if (null == from || null == sb) {
            throw new IllegalArgumentException("Miss arguments: from || sb");
        }
        if (null == to) {
            int indexFrom = sb.indexOf(from);
            if (indexFrom != -1) {
                //此处仅处理第一个匹配项
                sb.replace(indexFrom, indexFrom + from.length(), replace);
            }
        } else {
            int indexFrom = sb.indexOf(from);
            int indexTo = sb.indexOf(to);
            if (indexFrom != -1)
                //此处仅处理第一个匹配项
                sb.replace(indexFrom, indexTo + to.length(), replace);
        }
    }

    private void renderPagerInfo(String pagerInfo) throws IOException {
        if (pagerInfo == null) {
            pagerInfo = "";
        }
        getJspContext().getOut().write(pagerInfo);

    }


    static {
        try {
            templatePageS = (new PagerTag()).readFile(TEMPLATE_PAGE);
        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("page template:" + TEMPLATE_PAGE + " is not exist");
        }
    }

    private StringBuffer readFile(String filePath) throws IOException {
        StringBuffer _sb = new StringBuffer();
        InputStream in = PageTag.class.getResourceAsStream(filePath);
        BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        String temp = "";
        while ((temp = br.readLine()) != null) {
            _sb.append(temp);
            _sb.append("\n");
        }

        return _sb;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSearchForm() {
        return searchForm;
    }

    public void setSearchForm(String searchForm) {
        this.searchForm = searchForm;
    }

    public String getStyleType() {
        return styleType;
    }

    public void setStyleType(String styleType) {
        this.styleType = styleType;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getShowJumpBox() {
        return showJumpBox;
    }

    public void setShowJumpBox(String showJumpBox) {
        this.showJumpBox = showJumpBox;
    }

    public String getShowRowSelect() {
        return showRowSelect;
    }

    public void setShowRowSelect(String showRowSelect) {
        this.showRowSelect = showRowSelect;
    }

    public String getRowNumber() {
        return rowNumber;
    }

    public void setRowNumber(String rowNumber) {
        this.rowNumber = rowNumber;
    }

    public PageList getPageList() {
        return pageList;
    }

    public void setPageList(PageList pageList) {
        this.pageList = pageList;
    }
}
